package com.exonline.front.controller.pay;

import com.exonline.commons.utils.TokenUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @desc 支付的C层
 * @author hbrj
 */
@WebServlet("/font/pay")
public class PayServlet extends HttpServlet {

    // 使用Jackson库进行JSON格式的响应输出
    ObjectMapper mapper = new ObjectMapper();
    // 创建PayService对象 支付类，用于处理课程相关业务逻辑
    PayService service = new PayService();

    /**
     * @desc 支付的服务层 跳转支付  用户订单信息  学生个人中心的课程信息
     * @param req  客户端请求
     * @param resp 服务端响应
     * @throws ServletException 如果请求处理过程中发生错误
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        try {
            if ("skippay".equals(method)) {
                this.skipPay(req, resp);
            } else if ("successay".equals(method)) {
                this.successPay(req, resp);
            } else if ("orderinformation".equals(method)) {
                this.orderInformation(req, resp);
            } else if ("shoppingaccount".equals(method)) {
                this.shoppingaccount(req, resp);
            } else if ("judgmentBuying".equals(method)) {
                this.judgmentBuying(req, resp);
            }
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @desc  1.支付跳转 (沙箱支付) 前台支付订单信息  跳转到支付宝的支付订单信息页面
     * @param req 客户端请求
     * @param resp 服务端响应
     * @throws IOException 如果响应过程中发生I/O错误
     * @throws NoSuchAlgorithmException 如果加密算法不存在
     */
    private void skipPay(HttpServletRequest req, HttpServletResponse resp) throws IOException, NoSuchAlgorithmException {
        // 获取课程id
        String cid = req.getParameter("cid");
        // 根据token获取用户id
        String sid = TokenUtils.getId(req);
        if (sid == null || cid == null) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("code", 400);
            resultMap.put("msg", "参数不完整，请检查学生ID和课程ID是否正确传入");
            // 返回错误信息
            mapper.writeValue(resp.getWriter(), resultMap);
            return;
        }
        try {
            // 1.判断是否为免费课程
            boolean isFree = service.isCourseFree(cid);
            // 1.1判断为免费课程
            if (isFree) {
                // 1.2添加免费课程到个人课程
                boolean addedSuccessfully = service.addFreeCourseToStudent(sid, cid);
                if (addedSuccessfully) {
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("code", 200);
                    resultMap.put("msg", "免费课程已成功加入个人课程");
                    resultMap.put("data", true);
                    // 返回成功信息
                    mapper.writeValue(resp.getWriter(), resultMap);
                } else {
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("code", 500);
                    resultMap.put("msg", "添加免费课程到个人课程时出现错误");
                    resultMap.put("data", false);
                    // 返回错误信息
                    mapper.writeValue(resp.getWriter(), resultMap);
                }
                // 2.判断为收费课程
            } else {
                String payToken = TokenUtils.createPayToken(sid, cid);
                req.setAttribute("sid", sid);
                req.setAttribute("cid", cid);
                // 跳转到支付页面 跳转到支付宝的支付订单信息页面
                resp.sendRedirect("http://111.252.153.245:36815/EXOnline/admin/pay" + "?info=" + payToken);
            }
            // 捕获异常
        } catch (SQLException e) {
            e.printStackTrace();
            Map<String, Object> errorMap = new HashMap<>();
            errorMap.put("code", 500);
            errorMap.put("msg", "数据库操作出现错误，请联系管理员");
            // 返回错误信息
            mapper.writeValue(resp.getWriter(), errorMap);
        }
    }

    /**
     * @desc  2.成功支付 跳转
     * @param req 客户端请求
     * @param resp 服务端响应
     */
    private void successPay(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println(req.getParameter("outtradeno"));
    }

    /**
     * @desc  3. 用户订单信息
     * @param req 客户端请求
     * @param resp 服务端响应
     */
    private void orderInformation(HttpServletRequest req, HttpServletResponse resp) {
        try {
            // 根据token获取用户id（从session中获取sid）
            String sid = TokenUtils.getId(req);
            // 判断是否获取到用户id
            if (sid == null) {
                Map<String, Object> map = new HashMap<>();
                map.put("code", 400);
                map.put("msg", "未能从Session中获取到学生ID，请检查相关设置");
                // 返回错误信息
                mapper.writeValue(resp.getWriter(), map);
                return;
            }
            // 获取订单状态
            String status = req.getParameter("status");
            // 调用PayService的方法查询订单信息
            List<Map<String, Object>> orderList = service.queryOrdersBySid(sid, status);
            Map<String, Object> resultMap = new HashMap<>();
            // 判断查询结果是否为空
            if (orderList != null && !orderList.isEmpty()) {
                resultMap.put("code", 200);
                resultMap.put("msg", "订单信息查询成功");
                // 对查询到的订单列表中的每个订单记录，格式化其中的createtime字段
                formatCreateTimeInOrderList(orderList);
                resultMap.put("data", orderList);
            } else {
                resultMap.put("code", 400);
                resultMap.put("msg", "暂无订单信息或查询出现问题");
                resultMap.put("data", null);
            }
            // 将结果写入响应
            mapper.writeValue(resp.getWriter(), resultMap);
        } catch (IOException e) {
            e.printStackTrace();
            try {
                Map<String, Object> errorMap = new HashMap<>();
                errorMap.put("code", 500);
                errorMap.put("msg", "处理订单信息查询请求时出现错误");
                // 返回错误信息
                mapper.writeValue(resp.getWriter(), errorMap);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                Map<String, Object> errorMap = new HashMap<>();
                errorMap.put("code", 500);
                errorMap.put("msg", "数据库查询订单信息时出现错误");
                // 返回错误信息
                mapper.writeValue(resp.getWriter(), errorMap);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * 格式化订单列表中每个订单记录的createtime字段为指定的日期时间格式（yyyy-MM-dd HH:mm:ss）
     * @param orderList 包含订单记录的列表，每个元素是一个Map表示一条订单信息
     */
    private void formatCreateTimeInOrderList(List<Map<String, Object>> orderList) {
        // 创建SimpleDateFormat对象，指定日期时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 遍历订单列表，对每个订单记录进行格式化
        for (Map<String, Object> order : orderList) {
            Object createTimeObj = order.get("createtime");
            if (createTimeObj != null && createTimeObj instanceof Date) {
                try {
                    String formattedTime = sdf.format((Date) createTimeObj);
                    order.put("createtime", formattedTime);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @desc  4. 学生个人中心的课程信息判断
     * @param req 客户端请求
     * @param resp 服务端响应
     */
    private void judgmentBuying(HttpServletRequest req, HttpServletResponse resp) {
        try {
            //
            String sid = TokenUtils.getId(req);
            String cid = req.getParameter("cid");
            if (sid == null || cid == null) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("code", 400);
                resultMap.put("msg", "参数不完整，请检查学生ID和课程ID是否正确传入");
                resultMap.put("data", false);
                mapper.writeValue(resp.getWriter(), resultMap);
                return;
            }

            boolean isPurchased = service.isCoursePurchased(sid, cid);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("code", 200);
            if (isPurchased) {
                resultMap.put("msg", "课程已购买");
                resultMap.put("data", true);
            } else {
                resultMap.put("msg", "课程未购买");
                resultMap.put("data", false);
            }
            mapper.writeValue(resp.getWriter(), resultMap);
        } catch (IOException e) {
            e.printStackTrace();
            try {
                Map<String, Object> errorMap = new HashMap<>();
                errorMap.put("code", 500);
                errorMap.put("msg", "处理判断课程购买状态请求时出现错误");
                mapper.writeValue(resp.getWriter(), errorMap);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                Map<String, Object> errorMap = new HashMap<>();
                errorMap.put("code", 500);
                errorMap.put("msg", "数据库查询课程购买状态时出现错误");
                mapper.writeValue(resp.getWriter(), errorMap);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * @param req
     * @param resp
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @desc 购物车批量购买课程
     */
    private void shoppingaccount(HttpServletRequest req, HttpServletResponse resp) throws IOException, NoSuchAlgorithmException {
        /* // 读流
        Map map = mapper.readValue(req.getInputStream(), Map.class);
        String payToken = TokenUtils.createPayToken(TokenUtils.getId(req), map.get("cid").toString());

        //跳转到支付页面
        resp.sendRedirect("http://36.235.128.117:36815/EXOnline/admin/pay" + "?info=" + payToken);*/
        try {
            // 读取前端传入的包含购物车课程信息的JSON数据，解析为Map对象（假设前端传入的数据格式符合要求）
            Map<String, Object> map = mapper.readValue(req.getInputStream(), Map.class);
            // 获取学生ID，通过TokenUtils工具类从请求中提取（假设TokenUtils实现正确）
            String sid = TokenUtils.getId(req);
            if (sid == null) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("code", 400);
                resultMap.put("msg", "未能从请求中获取到学生ID，请检查相关设置");
                resultMap.put("data", false);
                mapper.writeValue(resp.getWriter(), resultMap);
                return;
            }

            // 从解析后的Map中获取课程ID列表，假设前端传入的JSON数据中课程ID列表对应的键是"cidList"，可根据实际调整
            List<String> cidList = (List<String>) map.get("cidList");
            if (cidList == null || cidList.isEmpty()) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("code", 400);
                resultMap.put("msg", "购物车课程ID列表不能为空，请检查传入数据");
                resultMap.put("data", false);
                mapper.writeValue(resp.getWriter(), resultMap);
                return;
            }

            // 获取PayService实例（假设已经正确初始化）
            PayService service = new PayService();

            // 遍历课程ID列表，对每门课程进行处理
            List<String> paidCidList = new ArrayList<>();
            for (String cid : cidList) {
                // 判断课程是否为免费课程
                boolean isFree = service.isCourseFree(cid);
                if (isFree) {
                    // 如果是免费课程，直接添加到学生个人课程表
                    boolean addedSuccessfully = service.addFreeCourseToStudent(sid, cid);
                    if (addedSuccessfully) {
                        continue;
                    } else {
                        // 如果添加失败，记录日志或者返回错误信息等（这里简单返回错误信息示例）
                        Map<String, Object> resultMap = new HashMap<>();
                        resultMap.put("code", 500);
                        resultMap.put("msg", "添加免费课程到个人课程时出现错误，课程ID: " + cid);
                        resultMap.put("data", false);
                        mapper.writeValue(resp.getWriter(), resultMap);
                        return;
                    }
                } else {
                    // 如果是收费课程，添加到待支付课程列表（这里用paidCidList记录收费课程ID，后续用于创建订单等操作）
                    paidCidList.add(cid);
                }
            }

            // 为收费课程创建订单记录（批量插入订单数据到数据库）
            boolean createOrderSuccess = service.createOrdersForCourses(sid, paidCidList);
            if (!createOrderSuccess) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("code", 500);
                resultMap.put("msg", "创建订单记录时出现错误，请联系管理员");
                resultMap.put("data", false);
                mapper.writeValue(resp.getWriter(), resultMap);
                return;
            }

            // 创建支付令牌，这里简单使用最后一门课程的ID等信息来生成（可根据实际业务逻辑调整，比如综合多门课程信息等更合理的方式）
            String payToken = TokenUtils.createPayToken(sid, paidCidList.get(paidCidList.size() - 1));

            // 跳转到支付页面
            resp.sendRedirect("http://36.235.128.117:36815/EXOnline/admin/pay" + "?info=" + payToken);
        } catch (SQLException e) {
            e.printStackTrace();
            Map<String, Object> errorMap = new HashMap<>();
            errorMap.put("code", 500);
            errorMap.put("msg", "数据库操作出现错误，请联系管理员");
            mapper.writeValue(resp.getWriter(), errorMap);
        }
    }






}
